package com.cloud.form.api.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.form.api.entity.FormAssemblyInst;
import com.cloud.form.api.entity.FormDataPush;
import com.cloud.form.api.entity.FormDataSet;
import com.cloud.form.api.entity.FormDef;
import com.cloud.form.api.enums.YesNoEnum;
import com.cloud.form.api.mapper.FormAssemblyInstMapper;
import com.cloud.form.api.mapper.FormDataPushMapper;
import com.cloud.form.api.mapper.FormDataSetMapper;
import com.cloud.form.api.mapper.FormDefMapper;
import com.cloud.form.api.service.FormDefService;
import com.cloud.form.common.result.QkIcon;
import com.cloud.form.common.result.QkTreeNode;
import com.cloud.form.common.utils.SessionHelper;
import com.cloud.form.common.utils.TreeHelper;

import tk.mybatis.mapper.entity.Example;

@Service
@Transactional
public class FormDefServiceImpl implements FormDefService {

	@Autowired
	private FormDefMapper formDefMapper;

	@Autowired
	private FormAssemblyInstMapper formAssemblyInstMapper;

	@Autowired
	private FormDataSetMapper formDataSetMapper;

	@Autowired
	private FormDataPushMapper formDataPushMapper;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public QkTreeNode[] listBizFormTree() {
		Example example = new Example(FormDef.class);
		example.setOrderByClause("biz_id, proc_def_id, display_order");
		List<FormDef> defs = formDefMapper.selectByExample(example);
		List<String> treeIdCache = new ArrayList<String>();
		List<QkTreeNode> nodes = new ArrayList<QkTreeNode>();
		for (FormDef def : defs) {
			if (!treeIdCache.contains("BIZ_" + def.getBizId())) {
				treeIdCache.add("BIZ_" + def.getBizId());
				QkTreeNode bizNode = new QkTreeNode("BIZ_" + def.getBizId(), def.getBizName());
				bizNode.setSelectable(false);
				bizNode.setRootFlag(true);
				bizNode.setExpanded(true);
				bizNode.setIcon(QkIcon.FA_LAPTOP);
				nodes.add(bizNode);
			}
			if (!treeIdCache.contains("PROC_" + def.getProcDefId())) {
				treeIdCache.add("PROC_" + def.getProcDefId());
				QkTreeNode procNode = new QkTreeNode("PROC_" + def.getProcDefId(), def.getProcDefName());
				procNode.setExpanded(true);
				procNode.setSelectable(false);
				procNode.setIcon(QkIcon.FA_FOLDER);
				procNode.setSeniorId("BIZ_" + def.getBizId());
				nodes.add(procNode);
			}
			treeIdCache.add("FORM_" + def.getFormId());
			QkTreeNode formNode = new QkTreeNode("FORM_" + def.getFormId(), def.getFormName());
			formNode.setSelectable(true);
			formNode.setLeaf(true);
			formNode.setIcon(QkIcon.FA_FILE_WORD);
			formNode.setSeniorId("PROC_" + def.getProcDefId());
			nodes.add(formNode);
		}
		return TreeHelper.buildList2Tree(nodes);
	}

	@Override
	public FormDef createUpdateForm(FormDef formDef) {
		Long formId = formDef.getFormId();
		formDef.setValidFlag(YesNoEnum.YES.getCode());
		if (null != formId && formId >= 0) {
			formDefMapper.updateByPrimaryKey(formDef);
		} else {
			formDef.setCreateUser(SessionHelper.get().getHumanName());
			formDef.setCreateTime(new Date());
			formDef.setFormId(formId);
			formDefMapper.insert(formDef);
		}
		return formDef;
	}

	@Override
	public long deleteForm(long formId) {
		// 数据推送
		Example dPushExample = new Example(FormDataPush.class);
		Example.Criteria dPushCriteria = dPushExample.createCriteria();
		dPushCriteria.andEqualTo("formId", formId);
		formDataPushMapper.deleteByExample(dPushExample);
		// 数据集
		Example dSetExample = new Example(FormDataSet.class);
		Example.Criteria dSetCriteria = dSetExample.createCriteria();
		dSetCriteria.andEqualTo("formId", formId);
		formDataSetMapper.deleteByExample(dSetExample);
		// 表单绘制对象
		Example assemblyExample = new Example(FormAssemblyInst.class);
		Example.Criteria assemblyCriteria = assemblyExample.createCriteria();
		assemblyCriteria.andEqualTo("formId", formId);
		formAssemblyInstMapper.deleteByExample(assemblyExample);
		// 表单定义
		Example formDefExample = new Example(FormDef.class);
		Example.Criteria formDefCriteria = formDefExample.createCriteria();
		formDefCriteria.andEqualTo("formId", formId);
		formDefMapper.deleteByExample(formDefExample);
		return formId;
	}

	@Override
	public FormDef loadFormDefById(long id) {
		return formDefMapper.selectByPrimaryKey(id);
	}

	@Override
	public Map<String, String> loadPrintForm(long id) {
		FormDef formDef = formDefMapper.selectByPrimaryKey(id);
		Map<String, String> result = new HashMap<String, String>();
		result.put("fileName", formDef.getFormName());
		List<String> fileContents = jdbcTemplate.queryForList("select form_print from form_def where form_id = ?",
				String.class, id);
		String fileContent = null;
		if (null != fileContents && fileContents.size() > 0 && !StringUtils.isEmpty(fileContents.get(0))) {
			fileContent = fileContents.get(0);
		} else {
			// 默认显示一个空的文件
			try {
				fileContent = Base64.getEncoder().encodeToString(IOUtils.toByteArray(
						FormDefServiceImpl.class.getClassLoader().getResourceAsStream("template/blank.doc")));
			} catch (IOException e) {
				throw new RuntimeException("读取文件失败，请检查文件是否存在", e);
			}
		}
		result.put("fileContent", fileContent);
		return result;
	}

	@Override
	public void uploadTemplate(long formId, String fileContent) {
		jdbcTemplate.update("update form_def set form_print = ? where form_id = ?", fileContent, formId);
	}

}
